﻿
using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;

//svnkit imports
using org.tmatesoft.svn.core;
using org.tmatesoft.svn.core.wc;

namespace Subsync.Core.Subversion
{
    /// <summary>
    /// SVN Checkout
    /// </summary>
    public class SVNMkdir : CommandBase
    {

        /// <summary>
        /// We have our variables declared here.
        /// Access modifiers as you can observe, is public. Why?
        /// Because we trust our programmers.
        /// 
        /// Try to be verbose with the variable names.
        /// Also, try to include *sane defaults*. Take peg_revision for eg.
        /// </summary>

        public SVNURL[] urls;
        public String commitMessage;
        public SVNProperties revisionProperties;
        public bool makeParents = true;

        /// <summary>
        /// Default constructor.
        /// </summary>
        public SVNMkdir()
        {
            //DEBUG MSG. *Always* include this.
            Debug.WriteLine("SVN Mkdir default Constructor");
        }

        /// <summary>
        /// Sane default constructor.
        /// </summary>
        /// <param name="urls">
        /// A <see cref="System.String"/>
        /// </param>
        /// <param name="commitMessage">
        /// A <see cref="System.String"/>
        /// </param>
        public SVNMkdir(String[] urls, String commitMessage)
        {
            //DEBUG MSG. *Always* include this.
            Debug.WriteLine("SVN Mkdir minimal Constructor with sane defaults");

            this.urls = new SVNURL[urls.Length];
            for (int i = 0; i < urls.Length; i++)
            {
                this.urls[i] = SVNURL.parseURIEncoded(urls[i]);
            }
            this.commitMessage = commitMessage;
        }

        /// <summary>
        /// Full constructor for Mkdir.
        /// </summary>
        /// <param name="urls">
        /// A <see cref="System.String"/>
        /// </param>
        /// <param name="commitMessage">
        /// A <see cref="System.String"/>
        /// </param>
        /// <param name="revisionProperties">
        /// A <see cref="SVNProperties"/>
        /// </param>
        /// <param name="makeParents">
        /// A <see cref="System.Boolean"/>
        /// </param>
        public SVNMkdir(String[] urls,
                        String commitMessage,
                        SVNProperties revisionProperties,
                        bool makeParents)
        {
            //DEBUG MSG. *Always* include this.
            Debug.WriteLine("SVN Mkdir normal Constructor");

            this.urls = new SVNURL[urls.Length];
            for (int i = 0; i < urls.Length; i++)
            {
                this.urls[i] = SVNURL.parseURIEncoded(urls[i]);
            }
            this.commitMessage = commitMessage;
            this.revisionProperties = revisionProperties;
            this.makeParents = makeParents;
        }

        /// <summary>
        /// Execute SVN Mkdir
        /// </summary>
        public override void Execute()
        {
            //DEBUG MSG. *Always* include this.
            Debug.WriteLine("SVN Mkdir Execution");

            //library setup
            Tools.setupLibrary();

            //load up the clients
            SVNClientManager cm = SVNClientManager.newInstance();
            SVNCommitClient cc = cm.getCommitClient();

            try
            {
                org.tmatesoft.svn.core.auth.BasicAuthenticationManager bam =
                    new org.tmatesoft.svn.core.auth.BasicAuthenticationManager("smalllittlecroc", "hh2Ey2QM7xW9");
                cc = new SVNCommitClient(bam, cm.getOptions());
                cc.doMkDir(this.urls, this.commitMessage);
            }
            catch (SVNException e)
            {
                //we convert this exception to a non SVNKit exception.
                //we want to minimize interfacing with SVNkit outside of this namespace (abstraction)
                throw new SVNExecuteException(e.getMessage());
            }
        }

        public override Dictionary<string, List<object>> getTokens()
        {
            Dictionary<string, List<object>> ret = new Dictionary<string, List<object>>();
            ret.Add("mkdir", new List<object>() { "mkdir" });
            return ret;
        }

        public override List<KeyValuePair<string, initPointer>> getInitPointers()
        {
            List<KeyValuePair<string, initPointer>> ret = new List<KeyValuePair<string, initPointer>>();
            ret.Add(new KeyValuePair<string, initPointer>("mkdir", new initPointer(this.handleCLI)));
            return ret;
        }

        public void handleCLI(Dictionary<string, List<object>> tokens)
        {
            if (tokens["mkdir"].Count < 1)
            {
                Console.WriteLine("Not enough arguments: Mkdir requires at least 1 argument (new folder name)");
                return;
            }
            
            this.urls = new SVNURL[1];
            string url = "";
            for (int i = 0; i < tokens["mkdir"].Count; i++)
            {
                url = (string)tokens["mkdir"][i];
                if(url.Contains("//"))
                {
                    this.urls[0] = SVNURL.parseURIEncoded(url);
                    this.Execute();
                }
                else
                {
                    try
                    {
                        Directory.CreateDirectory(url);
                        SVNClientManager cm = SVNClientManager.newInstance();
                        SVNWCClient wcc = cm.getWCClient();
                        wcc.doAdd(new java.io.File(url), false, false, false, SVNDepth.INFINITY, true, true, true);
                    }
                    catch (SVNException e)
                    {
                        throw new SVNExecuteException(e.getMessage());
                    }
                }
            }            
        }

    }
}
